home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / gprof / gpfsrc09.zoo / cplusdem.c < prev    next >
C/C++ Source or Header  |  1993-03-02  |  28KB  |  1,394 lines

  1. /* Demangler for GNU C++ 
  2.    Copyright (C) 1989, 1992 Free Software Foundation, Inc.
  3.    written by James Clark (jjc@jclark.uucp)
  4.    
  5.    This program is free software; you can redistribute it and/or modify
  6.    it under the terms of the GNU General Public License as published by
  7.    the Free Software Foundation; either version 2, or (at your option)
  8.    any later version.
  9.  
  10.    This program is distributed in the hope that it will be useful,
  11.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.    GNU General Public License for more details.
  14.  
  15.    You should have received a copy of the GNU General Public License
  16.    along with this program; if not, write to the Free Software
  17.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. /* This is for g++ 1.36.1 (November 6 version). It will probably
  20.    require changes for any other version.
  21.  
  22.    Modified for g++ 1.36.2 (November 18 version).
  23.  
  24.    Modified for g++ 1.90.06 (December 31 version).
  25.  
  26.    Modified for g++ 1.95.03 (November 13 verison).  */
  27.  
  28. /* This file exports one function
  29.  
  30.    char *cplus_demangle (const char *name)
  31.  
  32.    If NAME is a mangled function name produced by GNU C++, then
  33.    a pointer to a malloced string giving a C++ representation
  34.    of the name will be returned; otherwise NULL will be returned.
  35.    It is the caller's responsibility to free the string which
  36.    is returned.
  37.  
  38.    For example,
  39.    
  40.    cplus_demangle ("_foo__1Ai")
  41.    
  42.    returns
  43.  
  44.    "A::foo(int)"
  45.  
  46.    This file imports xmalloc and xrealloc, which are like malloc and
  47.    realloc except that they generate a fatal error if there is no
  48.    available memory. */
  49.  
  50. /* #define nounderscore 1 *//* define this is names don't start with _ */
  51.  
  52. #include <stdio.h>
  53. #include <ctype.h>
  54.  
  55. #ifdef USG
  56. #include <memory.h>
  57. #include <string.h>
  58. #else
  59. #include <strings.h>
  60. #define memcpy(s1, s2, n) bcopy ((s2), (s1), (n))
  61. #define memcmp(s1, s2, n) bcmp ((s2), (s1), (n))
  62. #define strchr index 
  63. #define strrchr rindex
  64. #endif
  65.  
  66. /* This is '$' on systems where the assembler can deal with that.
  67.    Where the assembler can't, it's '.' (but on many systems '.' is
  68.    used for other things).  */
  69. #if !defined (CPLUS_MARKER)
  70. #define CPLUS_MARKER '$'
  71. #endif
  72.  
  73. #ifndef __STDC__
  74. #define const
  75. #endif
  76.  
  77. #ifdef __STDC__
  78. extern char *cplus_demangle (const char *type);
  79. #else
  80. extern char *cplus_demangle ();
  81. #endif
  82.  
  83. #ifdef __STDC__
  84. extern char *xmalloc (int);
  85. extern char *xrealloc (char *, int);
  86. extern void free (char *);
  87. #else
  88. extern char *xmalloc ();
  89. extern char *xrealloc ();
  90. extern void free ();
  91. #endif
  92.  
  93. static char **typevec = 0;
  94. static int ntypes = 0;
  95. static int typevec_size = 0;
  96.  
  97. static struct {
  98.   const char *in;
  99.   const char *out;
  100. } optable[] = {
  101.   "nw", " new",            /* new (1.92, ansi) */
  102.   "dl", " delete",        /* new (1.92, ansi) */
  103.   "new", " new",        /* old (1.91) */
  104.   "delete", " delete",        /* old (1.91) */
  105.   "ne", "!=",            /* old, ansi */
  106.   "eq", "==",            /* old, ansi */
  107.   "ge", ">=",            /* old, ansi */
  108.   "gt", ">",            /* old, ansi */
  109.   "le", "<=",            /* old, ansi */
  110.   "lt", "<",            /* old, ansi */
  111.   "plus", "+",            /* old */
  112.   "pl", "+",            /* ansi */
  113.   "apl", "+=",            /* ansi */
  114.   "minus", "-",            /* old */
  115.   "mi", "-",            /* ansi */
  116.   "ami", "-=",            /* ansi */
  117.   "mult", "*",            /* old */
  118.   "ml", "*",            /* ansi */
  119.   "aml", "*=",            /* ansi */
  120.   "convert", "+",        /* old (unary +) */
  121.   "negate", "-",        /* old (unary -) */
  122.   "trunc_mod", "%",        /* old */
  123.   "md", "%",            /* ansi */
  124.   "amd", "%=",            /* ansi */
  125.   "trunc_div", "/",        /* old */
  126.   "dv", "/",            /* ansi */
  127.   "adv", "/=",            /* ansi */
  128.   "truth_andif", "&&",        /* old */
  129.   "aa", "&&",            /* ansi */
  130.   "truth_orif", "||",        /* old */
  131.   "oo", "||",            /* ansi */
  132.   "truth_not", "!",        /* old */
  133.   "nt", "!",            /* ansi */
  134.   "postincrement", "++",    /* old */
  135.   "pp", "++",            /* ansi */
  136.   "postdecrement", "--",    /* old */
  137.   "mm", "--",            /* ansi */
  138.   "bit_ior", "|",        /* old */
  139.   "or", "|",            /* ansi */
  140.   "aor", "|=",            /* ansi */
  141.   "bit_xor", "^",        /* old */
  142.   "er", "^",            /* ansi */
  143.   "aer", "^=",            /* ansi */
  144.   "bit_and", "&",        /* old */
  145.   "ad", "&",            /* ansi */
  146.   "aad", "&=",            /* ansi */
  147.   "bit_not", "~",        /* old */
  148.   "co", "~",            /* ansi */
  149.   "call", "()",            /* old */
  150.   "cl", "()",            /* ansi */
  151.   "cond", "?:",            /* old */
  152.   "alshift", "<<",        /* old */
  153.   "ls", "<<",            /* ansi */
  154.   "als", "<<=",            /* ansi */
  155.   "arshift", ">>",        /* old */
  156.   "rs", ">>",            /* ansi */
  157.   "ars", ">>=",            /* ansi */
  158.   "component", "->",        /* old */
  159.   "rf", "->",            /* ansi */
  160.   "indirect", "*",        /* old */
  161.   "method_call", "->()",    /* old */
  162.   "addr", "&",            /* old (unary &) */
  163.   "array", "[]",        /* old */
  164.   "vc", "[]",            /* ansi */
  165.   "compound", ",",        /* old */
  166.   "cm", ",",            /* ansi */
  167.   "nop", "",            /* old (for operator=) */
  168.   "as", "=",            /* ansi */
  169.   "cond", "?:",            /* old */
  170.   "cn", "?:",            /* psuedo-ansi */
  171.   "max", ">?",            /* old */
  172.   "mx", ">?",            /* psuedo-ansi */
  173.   "min", "<?",            /* old */
  174.   "mn", "<?",            /* psuedo-ansi */
  175. };
  176.  
  177. /* Beware: these aren't '\0' terminated. */
  178.  
  179. typedef struct {
  180.   char *b;            /* pointer to start of string */
  181.   char *p;            /* pointer after last character */
  182.   char *e;            /* pointer after end of allocated space */
  183. } string;
  184.  
  185. #ifdef __STDC__
  186. static void string_need (string *s, int n);
  187. static void string_delete (string *s);
  188. static void string_init (string *s);
  189. static void string_clear (string *s);
  190. static int string_empty (string *s);
  191. static void string_append (string *p, const char *s);
  192. static void string_appends (string *p, string *s);
  193. static void string_appendn (string *p, const char *s, int n);
  194. static void string_prepend (string *p, const char *s);
  195. static void string_prepends (string *p, string *s);
  196. static void string_prependn (string *p, const char *s, int n);
  197. static int get_count (const char **type, int *count);
  198. static int do_args (const char **type, string *decl);
  199. static int do_type (const char **type, string *result);
  200. static int do_arg (const char **type, string *result);
  201. static int do_args (const char **type, string *decl);
  202. static int do_cuv_prefix (const char **type, string *result, int *non_empty);
  203. static int do_builtin_type (const char **type, string *result, int *non_empty);
  204. static int do_template_args (const char **type, string *result);
  205. static void munge_function_name (string *name);
  206. static void remember_type (const char *type, int len);
  207. #else
  208. static void string_need ();
  209. static void string_delete ();
  210. static void string_init ();
  211. static void string_clear ();
  212. static int string_empty ();
  213. static void string_append ();
  214. static void string_appends ();
  215. static void string_appendn ();
  216. static void string_prepend ();
  217. static void string_prepends ();
  218. static void string_prependn ();
  219. static int get_count ();
  220. static int do_args ();
  221. static int do_type ();
  222. static int do_arg ();
  223. static int do_args ();
  224. static int do_cuv_prefix ();
  225. static int do_builtin_type ();
  226. static int do_template_args ();
  227. static void munge_function_name ();
  228. static void remember_type ();
  229. #endif
  230.  
  231. int
  232. get_simple_count (type, res)
  233.      char **type;
  234.      int *res;
  235. {
  236.   int n = 0, success = 1;;
  237.   
  238.   do
  239.     {
  240.       n *= 10;
  241.       n += **type - '0';
  242.       *type += 1;
  243.     } 
  244.   while (isdigit (**type));
  245.   if (strlen (*type) < n)
  246.     {
  247.       success = 0;
  248.     }
  249.  
  250.   *res = n;
  251.   return success;
  252. }
  253.  
  254. char *
  255. cplus_demangle (type)
  256.      const char *type;
  257. {
  258.   string decl;
  259.   int n;
  260.   int success = 0;
  261.   int constructor = 0;
  262.   int destructor = 0;
  263.   int static_type = 0;
  264.   int const_flag = 0;
  265.   int i;
  266.   const char *p;
  267. #ifndef LONGERNAMES
  268.   const char *premangle;
  269. #endif
  270.  
  271.   if (type == NULL || *type == '\0')
  272.     return NULL;
  273. #ifndef nounderscore
  274.   if (*type++ != '_')
  275.     return NULL;
  276. #endif
  277.   p = type;
  278.   while (*p != '\0' && !(*p == '_' && p[1] == '_'))
  279.     p++;
  280.   if (*p == '\0')
  281.     {
  282.       /* destructor */
  283.       if (type[0] == '_' && type[1] == CPLUS_MARKER && type[2] == '_')
  284.     {
  285.       destructor = 1;
  286.       p = type;
  287.     }
  288.       /* virtual table "_vt$"  */
  289.       else if (type[0] == '_' && type[1] == 'v' && type[2] == 't' && type[3] == CPLUS_MARKER)
  290.     {
  291.       int n = strlen (type + 4) + 14 + 1;
  292.       char *tem = (char *) xmalloc (n);
  293.       strcpy (tem, type + 4);
  294.       strcat (tem, " virtual table");
  295.       return tem;
  296.     }
  297.       /* static data member */
  298.       el